/*注意，当前程序最多写入1KB的数据*/
#include "stm32f0xx_hal.h"
#include <string.h>
#include "usart.h"

#define USER_FLASH_START  0x08003C00
#define USER_FLASH_END    0x08003FFF

// 安全写入函数
HAL_StatusTypeDef Safe_Flash_Write(uint32_t address, uint8_t *data, uint32_t length)
{
    // 1. 基本参数检查
    if(data == NULL || length == 0) return HAL_ERROR;
    
    // 2. 地址范围检查
    if(address < USER_FLASH_START || 
       (address + length) > (USER_FLASH_END + 1)) {
        return HAL_ERROR;
    }
    
    // 3. 擦除相关页
    uint32_t first_page = (address - USER_FLASH_START) / FLASH_PAGE_SIZE;
    uint32_t num_pages = ((address + length - 1) - USER_FLASH_START) / FLASH_PAGE_SIZE - first_page + 1;
    
    FLASH_EraseInitTypeDef erase;
    erase.TypeErase = FLASH_TYPEERASE_PAGES;
    erase.PageAddress = USER_FLASH_START + first_page * FLASH_PAGE_SIZE;
    erase.NbPages = num_pages;
    
    uint32_t page_error;
    if(HAL_FLASHEx_Erase(&erase, &page_error) != HAL_OK) {
        return HAL_ERROR;
    }
    
    // 4. 写入数据
    uint32_t *p_data = (uint32_t*)data;
    uint32_t words = (length + 3) / 4; // 向上取整计算字数
    
    HAL_FLASH_Unlock();
    
    for(uint32_t i = 0; i < words; i++) {
        if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, 
                           address + i*4, 
                           p_data[i]) != HAL_OK) {
            HAL_FLASH_Lock();
            return HAL_ERROR;
        }
    }
    
    HAL_FLASH_Lock();
    return HAL_OK;
}

void FLASH_ReadData(uint32_t Address, uint8_t *pData, uint32_t Length)
{
    for(uint32_t i = 0; i < Length; i++)
    {
        pData[i] = *(__IO uint8_t*)(Address + i);
    }
}

void Save_Configuration(void)
{
    typedef struct {
        uint8_t param1;
        uint8_t param2;
        uint8_t  param3;
        uint8_t crc; // 校验值
    } ConfigType;
    
    ConfigType config = {
        .param1 = 4,
        .param2 = 3,
        .param3 = 2,
        .crc = 0 // 实际使用时应计算CRC
    };
    
    // 计算CRC(此处省略)
    // config.crc = Calculate_CRC(&config, sizeof(config)-4);
    
    if(Safe_Flash_Write(USER_FLASH_START, (uint8_t*)&config, sizeof(config)) == HAL_OK) {
        uint8_t msg[] = "Configuration saved successfully!\n";
        HAL_UART_Transmit(&huart1, msg, sizeof(msg)-1, 100);
    } else {
        uint8_t msg[] = "Failed to save configuration!\n";
        HAL_UART_Transmit(&huart1, msg, sizeof(msg)-1, 100);
    }
}

